<?php
namespace MobileHome\Controller;

include_once __DIR__ . '/ZaCasher/ZaCashierPay.php';
require_once __DIR__ . '/ZhongAn/ZaCommon/common/ZhongAnApiClient.php';

class ProductController extends BaseController
{
    private $_mdlProduct = null;

    public function __construct()
    {
        parent::__construct();
        $this->_mdlProduct = M('Product');
    }

    /**
     * 产品列表
     */
    public function listAction()
    {
        $offset = I('get.offset', 0);
        $pageSize = I('get.limit', 10);
        $condition = [];
        $totalCount = $this->_mdlProduct->where($condition)->count();
        $list = $this->_mdlProduct->where($condition)->order('createTime desc')->limit($offset, $pageSize)->select();
        $data = [
            'totalCount' => $totalCount,
            'list' => $list,
        ];
        $this->json(200, 'SUCCESS', $data);
    }

    /**
     * 商品详情
     */
    public function detailAction()
    {
        $id = I('get.id', 0);
        $info = $this->_mdlProduct->find($id);
        $data = [
            'total' => 100,
            'datas' => $info,
        ];
        $this->json(200, 'SUCCESS', $data);
    }

    /**
     * 购买
     * @link http://open.zhongan.com/open/apidoc/docDetail.htm?docId=005&docMenu=doc_shyt_menu&docFile=doc_shyt_5
     */
    public function buyAction()
    {
        $orderNo = date('YmdHis') . rand(1000, 9999);
        $channelId = 22;
        $productNo = I('post.productNo');
        $coverage = I('post.coverage');
        $holderName = I('post.holderName');
        $holderCertType  = I('post.holderCertType ');
        $holderCertNo = I('post.holderCertNo');
        $holderEmail = I('post.holderEmail');
        $holderTel = I('post.holderTel');
        $insureName = I('post.insureName');
        $insureCertType = I('post.insureCertType');
        $insureCertNo = I('post.insureCertNo');
        $transNo = I('post.transNo');
        $trailerNo = I('post.trailerNo');
        $freightNo  = I('post.freightNo');
        $expectStartTime = date('Y-m-d H:i:s', strtotime(I('post.expectStartTime')));
        $departurePlace = I('post.departurePlace');
        $isShowPremium = I('post.isShowPremium');
        $compensationLimit = I('post.compensationLimit');
        $einvoice = I('post.einvoice');
        $taxpayerRegNum = I('post.taxpayerRegNum');
        $data = [
            'userId' => $_SESSION['user_id'],
            'channelOrderNo' => $orderNo,
            'channelId' => $channelId,
            'productNo' => $productNo,
            'coverage' => $coverage,
            'holderName' => $holderName,
            'holderCertType' => $holderCertType,
            'holderCertNo' => $holderCertNo,
            'holderEmail' => $holderEmail,
            'holderTel' => $holderTel,
            'insureName' => $insureName,
            'insureCertType' => $insureCertType,
            'insureCertNo' => $insureCertNo,
            'transNo' => $transNo,
            'trailerNo' => $trailerNo,
            'freightNo' => $freightNo,
            'expectStartTime' => $expectStartTime,
            'departurePlace' => $departurePlace,
            'isShowPremium' => $isShowPremium,
            'compensationLimit' => $compensationLimit,
            'einvoice' => $einvoice,
            'taxpayerRegNum' => $taxpayerRegNum,
            'createTime' => date('Y-m-d H:i:s'),
            'updateTime' => date('Y-m-d H:i:s'),
        ];
    }

    /**
     * 整车投保接口
     * @link http://open.zhongan.com/open/apidoc/docDetail.htm?docId=005&docMenu=doc_api_menu&docFile=doc_api_5
     *
     * 接口名称：zhongan.cargo.common.applyValidateByCar
     * 接口入参：入参为字符串格式
     */
    public function applyAction()
    {
        require_once __DIR__ . '/ZhongAn/ZaCommon/common/ZhongAnApiClient.php';

        // 指定环境 iTest:测试环境; uat:预发环境; prd:生产环境
        $_env = "dev";

        // 开发者的appKey，由众安提供
        $_appKey = "56aeb235013ba30c503f6087333fd063";
        // d7ba23de065aac3479e86dd0bcd51f90 uat
        // 3ee877531b114794eb18bbcff859c482 iTest

        // 开发者的私钥，由开发者通过openssl工具生成，不需要PKCS8转码
        $_privateKey = "-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDjQ2r5GvLNCl/ME6LZ7meoEXoBwsuve9neZIMuc5Kj9fiqom/v
JLRy/cb0wrD0QFoqCXvofQM35SGB9sqO4BPeSFPRO16ux0Wov2YA+1bwfwREnIgv
MrNI7l0yhMTe02m3Uy180/zPYBRt5PXJrGuLDDPkcgqWluDe2SRfqO+QewIDAQAB
AoGBAIsNPg+q+HKSbWjtfs//OfcwskkPihcWHYkgUM+EMW4W2w50ky5sc+iD9E7g
LOtV0JU19lWa3/Q8QxNFEEz5N827oTJngDPrXgpsTwnIJx7o1Z/LYj9Z49umloDP
+4FzBiizsX+tD4mAB+pt90EikTWjGYRjdqF93vs9GxJ/onUhAkEA8qf5csMJmsPj
jiO8682nKGRqoE8kd798Z8LhPjbn8JIUAj7GEGxXgmWpcWXl7m/IaC/dyUWP3vnD
EbusCt30qwJBAO/Cv8syM3r7U6dRo3B8wqHOxxnJq9dPQwusj5uaUkqrywOXz1ID
e30RZNlKN9yJOFgc7XrnydrG0Qg9EXKps3ECQQCWMu8u4Bbz20jhVLG96+AKGo39
iL9z9+0TdQdjMS1ENcd41E5ZIBbSuga2EHLQshSEmQxZZ1t0k3jxYw9M8rJdAkEA
2KpNV/rNut1UA2grIoQb/s0173/n4nKmS+5s+FjE9OW6WEzf9WVgOu11DUeco5b9
a+L4WJEOQL5aN++3zL6+gQJBAKmK4VchU5xch4Uz3QYRyqa4IhX4oHcuxNx/ZLYM
gHVR7Nx3ZT4bD/53CqCbT4/IVNOl7JC6GS4s/s3Y9sg/vpQ=
-----END RSA PRIVATE KEY-----";

        // 指定服务名，由众安提供
        $_serviceName = "zhongan.cargo.common.applyValidateByCar";

        // 业务参数，字段信息参照接口文档
        $_params = [
            'channelOrderNo' => '11111', //渠道订单号，唯一不可重复
            'channelId' => '1968', //渠道ID,固定值，由众安指定并提供
            'productNo' => '1416c49773a6a0980e5f00943756b31377ea701f4c6b', //产品ID,固定值，由众安指定并提供
            'coverage' => '100', //保额
            'holderName' => '王乐乐', //投保人名称
            'holderCertType' => 'TY', //投保人证件类型（TY：统一社会信用代码, Z：组织机构代码证; 默认TY）
            'holderCertNo' => '410602198903214511', //投保人证件号码
            'holderEmail' => '291518@qq.com',
            'holderTel' => '18116456783',
            'insureName' => '小鱼儿', //被保险人名称
            'insureCertType' => 'TY', //被保险人证件类型（TY：统一社会信用代码, Z：组织机构代码证; 默认TY）
            'insureCertNo' => '410602198703214511', //被保险人证件号码
            'transNo' => 'F2345', //车辆牌照号
            'trailerNo' => '挂34345', //挂车车牌号(5-10个字符，需包含‘挂’字)
            'freightNo' => '342435353536', //发票号/提单号/运单号
            'expectStartTime' => date('Y-m-d H:i:s'), //起运日期
            'departurePlace' => '', //起运地(按照国标：由众安提供)
            'destinationPlace' => '', //目的地(按照国标：由众安提供)
            'isShowPremium' => '', //是否显示费率及保费(即在电子保单中是否展示费率及保费)
            'compensationLimit' => '100万', //责任限额(取值范围：100万、150万、200万、250万、300万)
            'einvoice' => 'Y', //电子发票标识(Y：索要电子发票, N：不索要电子发票)
            'taxpayerRegNum' => '23423455', //纳税人识别号( 如果einvoice为Y，并且投保人为公司，taxpayerRegNum则必)
            'createTime' => date('Y-m-d H:i:s'),
            'updateTime' => date('Y-m-d H:i:s'),
        ];
        $_client = new \ZhongAnApiClient ($_env, $_appKey, $_privateKey, $_serviceName, 'UTF-8', 'RSA', '1.0.1');
        $params['param'] = $_params;
        $_response = $_client->call($params);
        var_dump($_response ["bizContent"]);
    }

    /**
     * 获取收银台支付链接
     * 此接口支持重复调用,前提是交易基本信息(交易金额、超时时间等)在多次调用中保持一致,且交易尚未完成支付;
     * 商户通过https post参数调用收银台接口进行支付.
     * 某些参数非必传，记得去掉该参数。传空值会导致验签失败。参数值请不要放入奇怪符号如：#、%等。
     *
     * @link http://open.zhongan.com/open/apidoc/docDetail.htm?docId=005&docMenu=doc_shyt_menu&docFile=doc_shyt_5
     */
    public function getPayUrlAction()
    {
        //格式必须是对象形式: 例 'order_info'=>'{"被保人":"XXX","保险期限":"XXXX"}',       //产品详情  json格式
        $orderInfo = json_encode([
            1 => 'ceshi1',
            'sagerg',
        ]);
        $notifyInfo = json_encode([
            'ceshi' => "333",
        ]);
        $requestData = [
            'request_charset' => 'UTF-8',  //编码
            'sign_type'       => 'MD5', //签名方式
            'out_trade_no'    => '1234552267a22bc', //商户订单号
            'merchant_code'   => C('ZONGAN.merchant_code'), //商户编码
            'subject'         => 'XXX保险', //产品名称
            'body'            => '描述',  //产品描述
            'amt'             => 1, //支付金额 单位:元
            'expiry_time'     => 30, //订单有效时间  单位：分钟
            'pay_channel'     => 'alipay^wxpay^anthb', //支付渠道：默认全开通 alipay^wxpay^anthb
            'src_type'        => 'mobile',  //来源类型 pc/mobile   电脑端/移动端
            'order_type'      => 'insurance', //订单类型：默认保险订单
            'show_url'        => C('SITE_URL') . '',  //商品地址
            'notify_url'      => C('SITE_URL') . C('ZONGAN.notify_url'), //服务器通知回调url
            'back_url'        => C('SITE_URL') . C('ZONGAN.back_url'),  //关闭跳转return_url
            'return_url'      => C('SITE_URL') . C('ZONGAN.return_url'),  //前端跳转url
            'notify_info'     => $notifyInfo,  //公用回传参数  json格式
            'order_info'      => $orderInfo,       //产品详情  json格式
            'help_pay'        => 1, //	是否支持代付 (0:支持，1:不支持，默认支持)
            'jump_time'       => 10, //控制结果页面倒计时跳转时间,单位秒
        ];

        //设置配置
        $config = [
            'url' => C('ZONGAN.cashier_url'),
            'mechantCode' => C('ZONGAN.merchant_code'),
            'appKey' => C('ZONGAN.app_key'),
        ];
        if (!ZaCashierPay::setConfig($config)) {
            $this->json(4001, '获取支付链接失败[失败原因:' . ZaCashierPay::getError() . ']');
        }
        //获取支付url
        $redirectPayUrl = ZaCashierPay::createPayUrl($requestData);//获取支付url后，跳转过去就ok了。
        die($redirectPayUrl);
        if (!$redirectPayUrl) {
            $this->json(4002, '获取支付链接失败[失败原因:' . ZaCashierPay::getError() . ']');
        }
        //执行跳转，或返回url然后进行其他操作后跳转
        $data = [
            'payUrl' => $redirectPayUrl,
        ];
        $this->json(200, 'SUCCESS', $data);
    }

    /**
     * 处理支付成功后的页面跳转同步通知
     * 该页面中获得参数的方式，需要使用get方式获取; 该方式仅仅在付款用户付款完成以后进行自行跳转，所有只会进行一次。
     * 设置页面跳转同步通知的路径时，不要在页面文件后面加上自定义参数:
     * 错误的写法：http://www.zhongan.com/xxxx/return_url.htm?xx=aa
     * 正确的写法：http://www.zhongan.com/xxxx/return_url.htm
     * 众安保险建议商户业务逻辑的执行，以收到服务器异步通知为准。
     * 当商户有传递参数 notifyurl(服务器异步通知页面路径)或 returnurl(页面跳转 同步通知页面路径)时,商户必须根据众安保险不同类型的
     *      业务通知,正确的进行不同的业务处理，并且过滤重复的通知结果数据。如果商户未正确处理业务通知,存在潜在的风险,商户自行承担因此
     *      而产生的所有损失。
     *
     * @link http://open.zhongan.com/open/apidoc/docDetail.htm?docId=006&docMenu=doc_shyt_menu&docFile=doc_shyt_6
     */
    public function handleReturnUrlAction()
    {
        //日志记录回调url
        //请求白名单校验
        //校验通知信息,过滤重复的通知结果数据
        //处理订单状态
        //跳转到支付完成页面

        $notifyData=$_GET; //接收的get或post的参数

        //设置配置
        if(!ZaCashierPay::setConfig($this->_config)){
            exit('失败');
        }
        //验证签名
        if(!ZaCashierPay::validationSign($notifyData)){
            exit('失败');
        }
        //支付失败
        if($notifyData['pay_result'] !== 'S') {
            //失败后续操作
        }

        //进行其他自主操作，如判定支付状态、处理订单状态等
    }

    /**
     * 异步通知接口
     * 1)必须保证服务器异步通知页面（notify_url）上无任何字符，如空格、html标签、开发系统自带的抛出异常提示信息等；
     * 2)众安保险是用post方式发送通知信息，因此该页面中获取参数的方式需要使用post方式获得。
     * 3)众安保险主动发起通知。该方式才会被启用
     * 4)只有众安保险的交易管理中存在该笔交易，并且交易状态由【未支付】变为【支付成功】后，众安保险才会通过该方式发起服务器通知。
     * 5)第一次通知会和页面跳转同步通知一起发出。
     * 6)程序执行完后必须打印输出success。如果商户反馈给众安保险的字符不是success这7个字符，众安保险服务器会不断的重发通知，
     *      直到超过通知次数上限。通知间隔频率为：（0秒，5分钟，10分钟，30分钟，1小时，1小时，3小时，6小时，6小时，6小时），
     *      总共24小时10次。
     * 7)该方式的调试与运行必须在服务器上，即互联网上能访问；
     * 8)该方式通知形式可能存在多次通知模式，所以商户处理通知的服务务必需要做好幂等处理，对于同一订单，众安保险如果多次通知商户
     *      交易成功，商户应该只执行一次业务操作。
     *
     */
    public function notifyAction()
    {
        //日志记录回调url
        //请求白名单校验
        //校验通知信息,过滤重复的通知结果数据
        //处理订单状态
        //跳转到支付完成页面

        $notifyData=$_POST; //接收的get或post的参数

        //设置配置
        if(!ZaCashierPay::setConfig($this->_config)){
            exit('fail');
        }
        //验证签名
        if(!ZaCashierPay::validationSign($notifyData)){
            exit('fail');
        }
        //支付失败
        if($notifyData['pay_result'] !== 'S') {
            //失败后续操作
        }

        //进行其他自主操作，如判定支付状态、处理订单状态等

        exit('success');
    }
}